package org.whatever.aha.zjut.platform.service.competition;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.whatever.aha.zjut.base.constant.ErrorCode;
import org.whatever.aha.zjut.base.constant.StatusConstant;
import org.whatever.aha.zjut.base.exception.AppException;
import org.whatever.aha.zjut.platform.dto.competition.CompetitionStageAwardDto;
import org.whatever.aha.zjut.platform.dto.competition.CompetitionStageDto;
import org.whatever.aha.zjut.platform.entity.competition.CompetitionStage;
import org.whatever.aha.zjut.platform.entity.competition.CompetitionStageStatus;
import org.whatever.aha.zjut.platform.entity.project.Project;
import org.whatever.aha.zjut.platform.mapper.competition.CompetitionStageMapper;
import org.whatever.aha.zjut.platform.service.project.ProjectService;
import org.whatever.aha.zjut.platform.util.StatusConvertUtil;
import org.whatever.aha.zjut.platform.vo.competition.CompeletedCompInfoVo;
import org.whatever.aha.zjut.platform.vo.competition.CompetitionStageVo;
import org.whatever.aha.zjut.platform.vo.info.StatusInfoVo;

import java.util.*;

/**
 * @author Vc
 * @version 1.0
 * @Desc
 * @date 2021/08/23 2:16
 */
@Service
@RequiredArgsConstructor
public class CompetitionStageService {
    final CompetitionStageMapper competitionStageMapper;
    final CompetitionStageStatusService competitionStageStatusService;
    final ProjectService projectService;


    /**
     * 创建新的赛事阶段信息,返回插入成功的主键值
     *
     * @param compId
     * @param competitionStageDto
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public int addCompStage(int compId, CompetitionStageDto competitionStageDto){
        CompetitionStage competitionStage = new CompetitionStage();
        BeanUtils.copyProperties(competitionStageDto,competitionStage);
        competitionStage.setCompId(compId);
        competitionStageMapper.insert(competitionStage);
        return competitionStage.getStageId();
    }


    /**
     * 根据List创建新的赛事阶段信息
     *
     * @param compId
     * @param CompetitionStageDtoList
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public int addCompStageByList(int compId, List<CompetitionStageDto> CompetitionStageDtoList){
        CompetitionStageDtoList.forEach(competitionStageAwardDto->this.addCompStage(compId,competitionStageAwardDto));
        return CompetitionStageDtoList.size();
    }

    /**
     * 根据当前时间确定赛事阶段状态
     *
     * @param stageId
     * @return
     */
    public int getStageStatusByTime(int stageId){
        Date now = new Date();
        List<CompetitionStageStatus> compStageStatusList = competitionStageStatusService.getCompStageStatus(stageId);
        for(CompetitionStageStatus competitionStageStatus : compStageStatusList){
            if(competitionStageStatus.getStatusOrder() == StatusConstant.COMPETITION_STAGE_STATUS_ORDER_SUBMIT.getCode() && now.before(competitionStageStatus.getStatusStartTime())){
                return StatusConstant.COMPETITION_STAGE_STATUS_NOT_COMMENCED.getCode();
            }else if(competitionStageStatus.getStatusOrder() == StatusConstant.COMPETITION_STAGE_STATUS_ORDER_PROMULGATE.getCode() && now.after(competitionStageStatus.getStatusEndTime())){
                return StatusConstant.COMPETITION_STAGE_STATUS_COMPLETED.getCode();
            }else if(now.before(competitionStageStatus.getStatusEndTime()) && now.after(competitionStageStatus.getStatusStartTime())){
                return StatusConstant.COMPETITION_STAGE_STATUS_ONGOING.getCode();
            }
        }
        throw new AppException(ErrorCode.FIND_STAGE_STATUS_CURRENT_TIME_FAIL);
    }

    /**
     * 批量创建新的赛事阶段信息
     *
     * @param compId
     * @param compStageName
     * @param nextStageNum
     * @param compStageDesc
     * @param stageOrder
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public int addCompStageInBatch(List<Integer> compId, List<String> compStageName, List<Integer> nextStageNum, List<String> compStageDesc, List<Integer> stageOrder){
        List<CompetitionStage> cs = Collections.synchronizedList(new ArrayList<CompetitionStage>());
        for (int j = 0; j < compId.size(); j++){
            cs.add(new CompetitionStage(compId.get(j),null,compStageName.get(j),nextStageNum.get(j),compStageDesc.get(j),stageOrder.get(j), StatusConstant.COMPETITION_STAGE_STATUS_NOT_COMMENCED.getCode()));
        }
        return competitionStageMapper.insertBatchSomeColumn(cs);
    }


    /**
     * 删除一条赛事阶段信息
     * TODO 删除时同步删除award等依赖信息
     * @param compStageId
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public int delCompStage(int compStageId){
        if(competitionStageMapper.selectCount(new QueryWrapper<CompetitionStage>().eq("stage_id",compStageId))<1){
            throw new AppException(ErrorCode.COMPETITION_STAGE_LACK);
        }
        List<Project> projects = projectService.getProjectsByStageId(compStageId);
        for (Project project : projects) {
            projectService.deleteProjectById(project.getProjectId());
        }
        return competitionStageMapper.delete(new QueryWrapper<CompetitionStage>().eq("stage_id",compStageId));
    }


    /**
     * 获取当前阶段下一个阶段
     *
     * @param compId
     * @param stageId
     * @return
     */
    public int getNextStage(int compId, int stageId){
        int curStageOrder = competitionStageMapper.selectById(stageId).getStageOrder();
        List<Object> objects = competitionStageMapper.selectObjs(new QueryWrapper<CompetitionStage>().eq("comp_id", compId).eq("stage_order", curStageOrder + 1).select("stage_id"));
        return objects.isEmpty() ? 0 : (Integer) objects.get(0);
    }

    /**
     * 根据竞赛Id获取阶段Id List
     * baseMapper语句 selectObjs自带错误：SELECT   stage_id   FROM competition_stage     WHERE (comp_id) = ?)
     * @param compId
     * @return
     */
    public List<Integer> getStageIdByCompId(int compId){
        return competitionStageMapper.getStageIdByCompId(compId);
    }

    /**
     * 根据竞赛Id获取阶段信息 List
     *
     * @param compId
     * @return
     */
    public List<CompetitionStage> getStageByCompId(int compId){
        return competitionStageMapper.selectList(new QueryWrapper<CompetitionStage>().eq("comp_id",compId).orderByAsc("stage_order"));
    }

    /**
     * 根据 stageId 获得CompetitionStageVo
     *
     * @param stageId
     * @return
     */
    public CompetitionStageVo getStageVoById(int stageId){
        CompetitionStage competitionStage = competitionStageMapper.selectOne(new QueryWrapper<CompetitionStage>().eq("stage_id", stageId));
        CompetitionStageVo competitionStageVo = new CompetitionStageVo();
        BeanUtils.copyProperties(competitionStage, competitionStageVo);
        return competitionStageVo;
    }

    /**
     *  根据 compId 和 stageId 和 竞赛阶段Vo 更新竞赛阶段记录
     *
     * @param compId
     * @param stageId
     * @param competitionStageVo
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public int updateCompStageById(int compId, int stageId, CompetitionStageVo competitionStageVo){
        if(competitionStageMapper.selectCount(new QueryWrapper<CompetitionStage>().eq("stage_id",stageId))<1){
            throw new AppException(ErrorCode.COMPETITION_STAGE_LACK);
        }
        CompetitionStage competitionStage = new CompetitionStage();
        competitionStage.setCompId(compId);
        BeanUtils.copyProperties(competitionStageVo, competitionStage);
        return competitionStageMapper.update(competitionStage, new QueryWrapper<CompetitionStage>().eq("comp_id",compId).eq("stage_id",stageId));
    }

    /**
     *  根据 竞赛阶段 更新竞赛阶段记录
     *
     * @param competitionStage
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation= Propagation.REQUIRED)
    public int updateCompStageById(CompetitionStage competitionStage){
        if(competitionStageMapper.selectCount(new QueryWrapper<CompetitionStage>().eq("stage_id",competitionStage.getStageId()))<1){
            throw new AppException(ErrorCode.COMPETITION_STAGE_LACK);
        }
        return competitionStageMapper.update(competitionStage, new QueryWrapper<CompetitionStage>().eq("stage_id",competitionStage.getStageId()));
    }

    /**
     * 根据 compId 获取最后的阶段排名（初赛、复赛、复复赛  - 3）
     *
     * @param compId
     * @return
     */
    public int getStageLastOrder(int compId){
        List<Object> competitionStageOrders = competitionStageMapper.selectObjs(new QueryWrapper<CompetitionStage>().eq("comp_id", compId).select("stage_order").orderByDesc("stage_order"));
        return (int)competitionStageOrders.get(competitionStageOrders.size() - 1);
    }

    /**
     * 根据竞赛类型筛选出的竞赛中挑选已结束的阶段信息
     * @param maps
     * @return
     */
    public List<CompeletedCompInfoVo> getCompeletedStageInfo(List<Map<String, Object>> maps){
        ArrayList<CompeletedCompInfoVo> compeletedCompInfoVos = new ArrayList<>();
        for(Map<String, Object> map : maps){
            List<CompetitionStage> competitionStages = competitionStageMapper.selectList(new QueryWrapper<CompetitionStage>().eq("comp_id", map.get("comp_id")).eq("stage_status", StatusConstant.COMPETITION_STAGE_STATUS_COMPLETED.getCode()));
            if(!CollectionUtils.isEmpty(competitionStages)){
                List<StatusInfoVo> stageInfos = new ArrayList<>();
                for (CompetitionStage competitionStage : competitionStages) {
                    stageInfos.add(new StatusInfoVo(competitionStage.getStageId(), competitionStage.getStageName()));
                }
                CompeletedCompInfoVo compeletedCompInfoVo = CompeletedCompInfoVo.builder().compYear((Integer) map.get("comp_year"))
                        .stageInfo(stageInfos).build();
                compeletedCompInfoVos.add(compeletedCompInfoVo);
            }
        }
        return compeletedCompInfoVos;
    }

    /**
     * 获取进行中的竞赛阶段ID
     */
    public List<Object> getOngoingStageId(){
        return competitionStageMapper.selectObjs(new QueryWrapper<CompetitionStage>().eq("stage_status", StatusConstant.COMPETITION_STAGE_STATUS_ONGOING.getCode()).select("stage_id"));
    }

    /**
     * 根据stageId获取compId
     *
     * @param stageId
     * @return
     */
    public Integer getCompIdByStageId(int stageId){
        List<Object> objects = competitionStageMapper.selectObjs(new QueryWrapper<CompetitionStage>().eq("stage_id", stageId).select("comp_id"));
        if(CollectionUtils.isEmpty(objects)){
            throw new AppException(ErrorCode.STAGE_NOT_EXIT);
        }
        return (int)objects.get(0);
    }

}
